iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0
Security

從自建漏洞中學習 - 一起填坑吧系列 第 4

Redirects - 重新導向的資安漏洞們 (上篇)

  • 分享至 

  • xImage
  •  

Redirect 相關的資安漏洞們 (上篇)

Redirect - 一個我們經常會建立的功能

在建立一個網站服務時,我們經常會使用到 redirect。
此處舉一個例子,遇到的需求可能會像是: 我們想要導向外部網站的服務。

雖然 Redirect 有時可以帶給用戶良好的體驗,但若沒有適當處理就有可能會默默為我們埋下未爆彈,就默默讓用戶導向惡意網站了。

Redirect 相關的攻擊 1 - Open Redirects

常見攻擊手法

  • 採用發送垃圾郵件來釣魚:

    以下為範例 url:

     https://your_website.com/signin?redirect_uri=https://your_website_xxoo.coom/
    

    攻擊者嘗試將導向的網站替換成他們想要你被導向的惡意網站 (惡意網站通常會有相似的網站名稱)
    ->
    讓人在不經意間相信了該網站是我們原本正在造訪的網站
    ->
    最後輸入我們的訊息給惡意網站 (例如:帳號/密碼) or 不小心下載到惡意程式

    此處需要注意的是:

    如果他們可以將用戶“退回”到您的網站(一個明顯有效的域),他們的消息就不太可能被標記為惡意。如果用戶點擊該 link,使用者將在 link 中看到您的網站,但他們最終會到達攻擊者想要將他們導向到的任何站點。

要避免的寫法:

以 NodeJS 為例,在處理跨域 url 的時候,記得**不要**直接無意識 redirect,對要導向的網站毫無掌握

app.post('/buyItems', (req, res) => {
    // 像是在此處我們就直接導向 "req.query.redirect_url",沒有設立任何 allowlist 也沒過濾就導向了
    res.redirect(req.query.redirect_url ? req.query.redirect_url : '/');
});

如何防禦?

此處皆以 NodeJS 為例:

  • 建立 allowList,只允許導向 allowlist 中的 url

    app.post('/buyItems', (req, res) => {
      const allowlist = ['/test1', '/test2'];
      if (allowlist.indexOf(req.query.redirect_url) > -1) {
        res.redirect(req.query.redirect_url);
      } else {
        res.redirect('/');
      }
    });
    
  • 禁止任何 Offsite Redirects

    可以通過檢查 URL 來防止 redirect 到其他域,所以我們需要確保所有 redirect URL 都是相對路徑 (即它們以單個 / 字符開頭)。

    // redirect 前,可以使用以下方式來確認是否為 '/' 開頭的 url
    function getValidRedirect(url) {
      // 確認你的 url 是否是 '/' 開頭
      if (url.match(/^\/(?!\/)/)) {
          if (process.env.NODE_ENV == "development") {
              return '//127.0.0.1:3000' + url;
          }
          // For production
          return '//www.your_website.com' + url;
      }
    }
    

    注意!!:
    // 開頭的 URL 將被 Browser 解釋為與協議無關的絕對 URL —— 它們應該被拒絕。

  • 當要 Redirects 時,確認 Referrer :

    Redirect 到 query string 中傳遞的 URL 應該只由您網站上的頁面觸發。
    我們應該對任何觸發 redirect 的網站抱持懷疑態度,所以在執行 Redirects 的時候,
    請檢查 HTTP 請求中的 Referer 是否與您的域匹配

    範例:

    // 在 express 4 之後,我們可以使用 req.get('Referrer') 來取得 referrer
    req.get('Referrer');
    

    小百科:
    這邊的 HTTP Referrer(referer)是 HTTP header 的一個欄位,用來表示從哪個連結來到目前的網頁,採用的格式是 URL。
    -> 藉著 HTTP Referrer,目前的網頁可以檢查訪客從哪裡而來,這也常被用來對付偽造的跨網站請求

其他需要檢查的部分

  • 確認 Client-Side Code

    確保在使用 window.location 時,url 不會接收到不被信任的 input:
    也就是我們不要完全信賴使用者給我們的 Input 作為重新導向的 link


今日小心得

Redirect 要注意的事情真的是滿多的,如果真的要寫還會需要寫到 XSS 相關的攻擊,任何跟 url 相關的都不能放過,看來明日是需要來肝一下了,繼續加油!


Reference:


上一篇
Input (下篇)
下一篇
Redirects - 重新導向的資安漏洞們 (中篇)
系列文
從自建漏洞中學習 - 一起填坑吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言